package com.juyu.miliao.api.dao.redis;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.juyu.miliao.api.dao.mysql.GiftMultiplierInfoDao;
import com.juyu.miliao.api.domain.Gift;
import com.juyu.miliao.api.domain.GiftMultiplierInfo;
import com.juyu.miliao.api.domain.dto.WinInfoDTO;
import com.juyu.miliao.api.util.RandomUtil;
import com.juyu.miliao.common.constant.RedisKeyPrefix;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Repository;
import org.w3c.dom.ls.LSException;

import java.util.*;
import java.util.concurrent.TimeUnit;


/**
 * 水果机RedisDao
 *
 * @author xuanqicheng
 * @create 2019-15-14:50
 */
@Repository
public class FruitMachineRedisDao {

    public static final String  LUCK_DRAW_KEY = RedisKeyPrefix.MI_LIAO_API_KEY +"FRUIT_MACHINE_LUCK_DRAW:";


    public static final String  GIFT_MULTIPLIER_LIST_BY_GIFTID= RedisKeyPrefix.MI_LIAO_API_KEY+
            "GiftMultiplierListByGiftId:";

    public static final String GIFT_MULTIRLIER_GIFTID = RedisKeyPrefix.MI_LIAO_API_KEY+"GiftMultiplierGiftId";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private GiftMultiplierInfoDao giftMultiplierInfoDao;

    /**
     * 抽奖
     *
     * @param gift
     * @return
     */
    public WinInfoDTO getLuckDraw(Gift gift) {

        String key = LUCK_DRAW_KEY+gift.getGiftId();

        if (stringRedisTemplate.hasKey(key)) {

            String temp = stringRedisTemplate.opsForList().leftPop(key);

            WinInfoDTO winInfoDTO = JSONObject.parseObject(temp, WinInfoDTO.class);

            return winInfoDTO;

        } else {

            int size = gift.getNumber();

            //如果编号小于等于0 用户不中奖
            if (size <= 0) {
                return new WinInfoDTO().setStatus(2);
            }

            List<Integer> list = new LinkedList<>();

            List<WinInfoDTO> winInfoDTOList = new ArrayList<>();

            for (int i = 0; i < size; i++) {
                list.add(i);
                winInfoDTOList.add(new WinInfoDTO().setStatus(2));
            }

            List<GiftMultiplierInfo> giftMultiplierInfoList = getGiftMultiplierInfoList(gift.getGiftId());

            int giftNumbers = 0;

            for (GiftMultiplierInfo obj : giftMultiplierInfoList) {
                int number = obj.getWinningNumber() * obj.getMultiple();
                giftNumbers += number;
            }

            if (giftMultiplierInfoList.size() == 0 || size < giftNumbers) {

                return new WinInfoDTO().setStatus(2);
            }

            Set<Integer> indexSet = new HashSet<>();

            for (GiftMultiplierInfo obj : giftMultiplierInfoList) {

                if (obj.getWinningNumber() >= 0) {

                    if (obj.getWinningNumber()<list.size()) {
                        int[] ints = RandomUtil.randomCommon(0, list.size(), obj.getWinningNumber());
                        for (int i : ints) {
                            int index = list.get(i);

                            winInfoDTOList.get(index)
                                    .setGiftId(obj.getGiftId())
                                    .setGiftName(gift.getGiftName())
                                    .setMultiple(obj.getMultiple())
                                    .setStatus(1)
                                    .setGold(gift.getPrice() * obj.getMultiple());
                            indexSet.add(index);
                        }
                        list.removeAll(indexSet);
                    } else {

                        for (int i = 0; i < winInfoDTOList.size(); i++) {

                            if (!indexSet.contains(i)) {
                                winInfoDTOList.get(i)
                                        .setGiftId(obj.getGiftId())
                                        .setMultiple(obj.getMultiple())
                                        .setStatus(1)
                                        .setGold(gift.getPrice() * obj.getMultiple());
                            }
                        }
                    }
                }

            }

            setWinInfo(key,winInfoDTOList);
            if(stringRedisTemplate.hasKey(key)){

                String temp = stringRedisTemplate.opsForList().leftPop(key);

                WinInfoDTO winInfoDTO = JSONObject.parseObject(temp, WinInfoDTO.class);

                return winInfoDTO;
            }else{
                return new WinInfoDTO().setStatus(2);
            }

        }

    }


    /**
     * 设置中奖信息
     * @param key redis key
     * @param winInfoDTOList  中奖信息集合
     */
    private synchronized void setWinInfo(String key,List<WinInfoDTO> winInfoDTOList){
        boolean bl = stringRedisTemplate.hasKey(key);
        if(!bl){
            List<String> redisList = new ArrayList<>();
            for(WinInfoDTO winInfoDTO : winInfoDTOList){
                redisList.add(JSONObject.toJSONString(winInfoDTO));
            }

            stringRedisTemplate.opsForList().rightPushAll(key,redisList);
        }
    }


    private List<GiftMultiplierInfo>  getGiftMultiplierInfoList(int giftId){

        String key = GIFT_MULTIPLIER_LIST_BY_GIFTID+giftId;

        if(stringRedisTemplate.hasKey(key)){

            String temp = stringRedisTemplate.opsForValue().get(key);

            List<GiftMultiplierInfo> list = JSONArray.parseArray(temp, GiftMultiplierInfo.class);

            return list;
        }else{

            List<GiftMultiplierInfo> list = giftMultiplierInfoDao.selectByGiftId(giftId);

            stringRedisTemplate.opsForValue().set(key,JSONObject.toJSONString(list),10, TimeUnit.MINUTES);

            return list;
        }

    }

    public  List<Integer> getGiftIdListInfo(){

        String key = GIFT_MULTIRLIER_GIFTID;

        if(stringRedisTemplate.hasKey(key)){

            String temp = stringRedisTemplate.opsForValue().get(key);

            List<Integer> list = JSONArray.parseArray(temp,Integer.class);
            return list;
        }else{

            List<Integer> list = giftMultiplierInfoDao.selectGiftIdByGiftMultiplierList();
            stringRedisTemplate.opsForValue().set(key,JSONObject.toJSONString(list),5,TimeUnit.MINUTES);
            return list;
        }
    }


}
